// Master game class
//--------------------------------
#ifndef GAME_H
#define GAME_H
#include "common.h"
#include "message.h"
#include "io.h"
#include <boost/thread/thread.hpp>

class Game {
public:

    class SyncIO {
    public:

        ~SyncIO()
        {
            _lock.unlock();
        }

        IO&  _io;

        void Render()
        {
            _io.Render( _animation );
        }

    private:

        friend class Game;
        SyncIO( IO& io, char animation, boost::mutex& lock  )
        : _io( io ), _animation( animation ), _lock( lock )
        {
            _lock.lock();
        }

        boost::mutex& _lock;
        char          _animation;

    };

    static const uint        WIDTH;
    static const uint        HEIGHT;
    static const uint        MESSAGE_HEIGHT;
    static const uint        ANIMATION_TIME;
    #define                  TITLE "Madness"

    static const Colour      CUI_MAIN;
    static const Colour      CUI_HEAD;
    static const Colour      CUI_SUBH;
    static const Colour      CUI_BACK;
    static const Colour      CUI_BLACK;
    static const Colour      CUI_BAD;
    static const Colour      CUI_GOOD;
    static const Colour      CUI_WARNING;

    Game( IO& io );
    virtual ~Game();

    IO&    GetAsyncIO() const;
    SyncIO GetSyncIO()  const;
    void Run();

          Player* GetPlayer();
    const Player* GetPlayer() const;

    MessageBank& Bank();
    typedef std::vector< ustring >     MessageList;
    typedef std::vector< IO::SymList > FirstCharList;
    void QueueMessage( const     ustring& message, const IO::SymList& firstChar = IO::SymList() );
    void QueueMessage( const std::string& message, const IO::SymList& firstChar = IO::SymList() );
    void QueueMessage( const     ustring& message, uint before );
    void QueueMessage( const std::string& message, uint before );
    void DisplayMessages();
    void DisplayHistory();
    void DisplayNotes();

    void DestroyActor( Actor* a );
    void DestroyBuff ( Buff*  b );
    void DestroyItem ( Item*  i );
    void DeleteActors();
    void DeleteBuffs ();
    void DeleteItems ();

private:

    void                 AnimationRun();
    char                 _animation;
    mutable boost::mutex _animLock;

    ActorList _actorDestroyList;
    BuffList  _buffDestroyList;
    ItemList  _itemDestroyList;

    IO& _io;
    Player* _player;
    MessageList _messages;
    FirstCharList _firstChars;
    MessageList _allMessages;
    FirstCharList _allFirstChars;
    MessageBank _bank;

    std::vector< std::string > _notes;
    int _cx;
    int _cy;

};

typedef Game::SyncIO SyncIO;

#endif
